package roborally.program.conditions;

import be.kuleuven.cs.som.annotate.*;
import roborally.model.Robot;

/**
 * A class for dealing with not-conditions: (not(condition)).  
 * 
 * @invar	The condition of each not-condition must be a valid condition.
 * 			| canHaveAsCondition(getCondition())
 * 
 * @version	1.0
 * @author  Pieter Robberechts	(1e Bach Informatica)
 * @author	Jeroen Sanders		(1e Bach Informatica)
 *
 */
public class Not extends Condition {

	/**
	 * Initialize this new not-condition with a line number and a condition.
	 * 
	 * @param 	condition
	 * 			The condition to be evaluated.
	 * @pre		The given condition must be a valid one.
	 * 			| canHaveAsCondition(condition)
	 * @post	The given condition is set as the condition of this not-condition.
	 * 			| new.getCondition() == condition
	 */
	public Not(int lineNb, Condition condition) {
		super(lineNb);
		assert( canHaveAsCondition(condition) );
		this.condition = condition;
	}
	
	/**
	 * Variable registering the condition to be evaluated.
	 */
	private final Condition condition;
		
	/**
	 * Return the condition to be evaluated.
	 */
	@Basic @Raw @Immutable
	public Condition getCondition() {
		return condition;
	}
	
	/**
	 * Check whether the given condition is a valid one for a not-condition.
	 *  
	 * @param 	condition
	 * 			The condition to check for whether it is a valid one.
	 * @return	Return true if and only if the given condition is effective;
	 * 			else return false.
	 * 			| result == ( condition != null )
	 */
	@Raw
	public boolean canHaveAsCondition(Condition condition) {
		return ( condition != null );
	}

	/**
	 * Evaluate this condition for a given robot.
	 * 
	 * @return	Return true if and only if the condition of this not-condition
	 * 			evaluates to false; else return false.
	 * 			| result == ( super.evaluate(robot) && 
	 * 			|				! condition.evaluate(robot) )
	 */
	@Override
	public boolean evaluate(Robot robot) {
		return ( super.evaluate(robot) && ! condition.evaluate(robot) );
	}
	
	/**
	 * Return a textual representation of this not-condition,
	 * formatted in accordance with its position in the program.
	 * 
	 * @return	The result is a pretty formatted string of this not-condition,
	 * 			taking in account his relative position in the program.
	 * 			| result == 
	 * 			|		getIndentation(indentationLevel) + "(not\n" + 
	 *			|		getCondition().getIndentation(indentationLevel+1) + "\n)"
	 */
	@Override
	public String prettyFormat(int indentationLevel) {
		return getIndentation(indentationLevel) + "(not\n" + 
				getCondition().getIndentation(indentationLevel+1) + "\n)";
	}


}
